package com.star.spring.ratelimit.controller;

import java.util.HashMap;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;

import com.star.spring.ratelimit.annotation.RateLimit;
import com.star.spring.ratelimit.enums.RateLimitType;

import org.springframework.web.bind.annotation.*;

/**
 * 限流测试Controller
 *
 * @author star
 * @since 2025-01-24
 */
@Slf4j
@RestController
@RequestMapping("/api/rate-limit")
public class RateLimitTestController {

    /**
     * 本地令牌桶限流测试
     */
    @GetMapping("/token-bucket")
    @RateLimit(type = RateLimitType.LOCAL_TOKEN_BUCKET, count = 5, timeWindow = 60, message = "令牌桶限流：请求过于频繁")
    public Map<String, Object> tokenBucketTest() {
        log.info("Token bucket test - 令牌桶限流测试");

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "令牌桶限流测试成功");
        result.put("maxRequests", 10);
        result.put("windowSize", 60);
        result.put("timestamp", System.currentTimeMillis());
        return result;
    }

    /**
     * 本地滑动窗口限流测试
     */
    @GetMapping("/sliding-window")
    @RateLimit(type = RateLimitType.LOCAL_SLIDING_WINDOW, count = 5, timeWindow = 10, message = "滑动窗口限流：请求过于频繁")
    public Map<String, Object> slidingWindowTest() {
        log.info("Sliding window test - 滑动窗口限流测试");

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "滑动窗口限流测试成功");
        result.put("maxRequests", 5);
        result.put("windowSize", 10);
        result.put("timestamp", System.currentTimeMillis());
        return result;
    }

    /**
     * Redis固定窗口限流测试
     */
    @GetMapping("/redis-fixed")
    @RateLimit(type = RateLimitType.REDIS_FIXED_WINDOW, count = 20, timeWindow = 60, message = "Redis固定窗口限流：请求过于频繁")
    public Map<String, Object> redisFixedWindowTest() {
        log.info("Redis fixed window test - Redis固定窗口限流测试");

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "Redis固定窗口限流测试成功");
        result.put("maxRequests", 20);
        result.put("windowSize", 60);
        result.put("timestamp", System.currentTimeMillis());
        return result;
    }

    /**
     * Redis滑动窗口限流测试
     */
    @GetMapping("/redis-sliding")
    @RateLimit(type = RateLimitType.REDIS_SLIDING_WINDOW, count = 15, timeWindow = 60, message = "Redis滑动窗口限流：请求过于频繁")
    public Map<String, Object> redisSlidingWindowTest() {
        log.info("Redis sliding window test - Redis滑动窗口限流测试");

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "Redis滑动窗口限流测试成功");
        result.put("maxRequests", 15);
        result.put("windowSize", 60);
        result.put("timestamp", System.currentTimeMillis());
        return result;
    }

    /**
     * 基于IP的限流测试
     */
    @GetMapping("/ip-based")
    @RateLimit(type = RateLimitType.REDIS_FIXED_WINDOW, key = "#ip", count = 10, timeWindow = 60, message = "IP限流：该IP请求过于频繁")
    public Map<String, Object> ipBasedTest() {
        log.info("IP based test - IP限流测试");

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "IP限流测试成功");
        result.put("maxRequests", 10);
        result.put("windowSize", 60);
        result.put("timestamp", System.currentTimeMillis());
        return result;
    }

    /**
     * 基于用户ID的限流测试
     */
    @GetMapping("/user-based")
    @RateLimit(type = RateLimitType.REDIS_SLIDING_WINDOW, key = "#userId", count = 5, timeWindow = 30, message = "用户限流：该用户请求过于频繁")
    public Map<String, Object> userBasedTest(String userId) {
        log.info("User based test - userId: {}, 用户限流测试", userId);

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "用户限流测试成功");
        result.put("userId", userId);
        result.put("maxRequests", 5);
        result.put("windowSize", 30);
        result.put("timestamp", System.currentTimeMillis());
        return result;
    }

    /**
     * 自定义key的限流测试
     */
    @PostMapping("/custom-key")
    @RateLimit(type = RateLimitType.LOCAL_TOKEN_BUCKET, key = "'custom:' + #request.body", count = 3, timeWindow = 10, message = "自定义key限流：请求过于频繁")
    public Map<String, Object> customKeyTest(@RequestBody Map<String, Object> request) {
        log.info("Custom key test - request: {}, 自定义key限流测试", request);

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "自定义key限流测试成功");
        result.put("request", request);
        result.put("maxRequests", 3);
        result.put("windowSize", 10);
        result.put("timestamp", System.currentTimeMillis());
        return result;
    }

    /**
     * 无限流测试（对比用）
     */
    @GetMapping("/no-limit")
    public Map<String, Object> noLimitTest() {
        log.info("No limit test - 无任何限流限制");

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "无限流测试成功");
        result.put("timestamp", System.currentTimeMillis());
        return result;
    }
}
